﻿#pragma once

#ifndef BRIDGEANALYSIS_BRIDGE_ANALYSIS_H
#define BRIDGEANALYSIS_BRIDGE_ANALYSIS_H

// 文件项目
struct TFileItem
{
    char fileName[B256]; // 带扩展名不带路径的文件名称
    char extName[B256];  // 扩展名
    BOOL isFolder;       // 是否是目录
    int64_t fileSize;    // 文件大小【字节】
    int64_t createTime;  // 创建时间戳【自零时区1970.1.1 00:00:00起算的毫秒数】
    int64_t modifyTime;  // 修改时间戳【自零时区1970.1.1 00:00:00起算的毫秒数】
#ifdef _USRDLL
    // 构造函数
    TFileItem();
#endif
};

// 样品信息
struct TSample
{
    char ID[B64];             // 样品ID
    char Name[B64];           // 样品名称
    int32_t SmpType;          // 样品类型
    char MethodName[B64];     // 分析方法名称
    char InstName[B64];       // 仪器方法名称
    char BatchCode[B64];      // 样品批号
    char BslName[B256];       // 基线谱图全路径名称
    char GatherLocation[B64]; // 取样点
    int32_t GatherTime;       // 取样时间
    int32_t Minutes;          // 分析时长[0.01min]
    char ConcUnit[B64];       // 浓度单位(%,ppm,ppb,ppt,mg%mL,ug/mL,ng/mL,ng/L)
    int32_t CreateTime;       // 创建时间
    int32_t UpdateTime;       // 更新时间
    char Note[B128];          // 备注
#ifdef _USRDLL
    // 构造函数
    TSample();
#endif
};

// 进样信息
struct TInject
{
    char SmpID[B64];     // 样品ID
    char InjID[B64];     // 进样ID
    char GUID[B64];      // 全球唯一标识码
    int32_t Sn;          // 序列ID
    int32_t StartTime;   // 进样开始时间
    int32_t StopTime;    // 进样结束时间
    int32_t AnalMinutes; // 分析时长[0.01min]
    int32_t VialNos;     // 瓶号
    int32_t Syringe;     // 针序
#ifdef _USRDLL
    // 构造函数
    TInject();
#endif
};

#ifndef TAG_TINSTHEAD
#define TAG_TINSTHEAD
// 仪器条件头信息
struct TInstHead
{
    int32_t ID;                // ID
    char Name[B32];            // 仪器名
    int32_t Type;              // 仪器类别(GC, LC, IC, CE-毛细管电泳)
    char TypeAbbr[B8];         // 类别缩写
    char TypeName[B64];        // 类别名
    char Model[B32];           // 型号
    char MarkNo[B32];          // 设备号
    char Manufacturer[B64];    // 制造商
    int32_t SignalNo;          // 信号通路号
    BOOL FromAIACDF;           // 是否来自AIACDF
    char AIACDFName[B32];      // AIA-CDF文件名(不含扩展名)
    char Description[B128];    // 说明(备注)
    char ExperimentTitle[B64]; // 实验标题
    char DatasetOwner[B64];    // 谱图数据属源(单位名称)
    char OperatorName[B32];    // 操作者(分析员)
#ifdef _USRDLL
    // 构造函数
    TInstHead();
#endif
};
#endif

#ifndef TAG_TOVENCOND
#define TAG_TOVENCOND
// 柱温箱信息
struct TOvenCond
{
    BOOL Available;       // 是否有效
    int32_t MaxTempRamps; // 最大程升阶数
    double MaxTemp;       // 最高温度[K]
    double Equilibry;     // 平衡时间[min]
    char Model[B32];      // 型号
    double Temperature;   // 柱温[K]
    int32_t TempMode;     // 柱温模式(0-Constant Temp, 1-Programmed)
#ifdef _USRDLL
    // 构造函数
    TOvenCond();
#endif
};
#endif

#ifndef TAG_TINLETCOND
#define TAG_TINLETCOND
// 进样口信息
struct TInletCond
{
    BOOL Available;        // 是否有效
    int32_t Type;          // 类别
    char TypeAbbr[B8];     // 类别缩写
    char TypeName[B32];    // 类别名
    int32_t InjMode;       // 进样方式(Manual, GSV-气体进样阀, Auto Sampler)
    int32_t ASType;        // 自动进样器分类码(暂不使用)
    double InjVolume;      // 定量管体积[uL]
    char InjectModel[B32]; // 进样器型号
    int32_t TempMode;      // 进样口温度模式(0-Constant Temp, 1-Programmed(COC或PTV时))
    int32_t SplitMode;     // 分流方式(Splitless, Split)
    BOOL PurgeOn;          // 是否隔膜清洗
    double Temperature;    // 进样口温度[K]
    char CarrierGas[B8];   // 载气(N2, H2, He, ...)
    double CarrierFlow;    // 载气流速[mL/min]
    double Pressure;       // 进样口压力[psi]
    double SplitFlow;      // 分流流速[mL/min]
    char SplitRatio[B8];   // 分流比
    double PurgeFlow;      // 隔膜清洗流速[mL/min]
    double PurgeTime;      // 隔膜清洗时间[min]
    double SplitlessHold;  // 不分流保持时间
#ifdef _USRDLL
    // 构造函数
    TInletCond();
#endif
};
#endif

#ifndef TAG_TCOLUMNCOND
#define TAG_TCOLUMNCOND
// 色谱柱信息
struct TColumnCond
{
    BOOL Available;     // 是否有效
    int32_t Type;       // 类别(Packed, Capillary, Wide-Bore Capillary, HPLC Column, GPC Column, IC Column, Unknown)
    char TypeAbbr[B8];  // 类别缩写
    char TypeName[B32]; // 类别名
    int32_t FreqIdx;    // 采样频率索引号(0-高速,1-快速,2-中速,3-慢速,4-低速)
    int32_t mmLength;   // 柱长[mm]
    double Diameter;    // 内径[mm]
    double FilmThick;   // 膜后[μm]
    double DeadTime;    // 死时间[min]
    char Model[B32];    // 型号
    double Flow;        // 柱流量[mL/min]
    double Pressure;    // 柱压[psi]
    int32_t PFMode;     // 柱压力/流量模式(Const Pressure, Const Flow, Programmed Pressure, Programmed Flow)
#ifdef _USRDLL
    // 构造函数
    TColumnCond();
#endif
};
#endif

#ifndef TAG_TDETECTCOND
#define TAG_TDETECTCOND
// 检测器信息
struct TDetectCond
{
    BOOL Available;         // 是否有效
    int32_t Type;           // 类别(FID, TCD, ECD, NPD, FPD, PID, HID-氦离子化检测器, MSD, UVD, RID, DAD, FD, ECD-电化学, CD-电导, ELSD-蒸发光散射)
    char TypeAbbr[B8];      // 类别缩写
    char TypeName[B32];     // 类别名
    char Model[B32];        // 型号
    double RangeMax;        // 响应最大值
    double RangeMin;        // 响应最小值
    double RangeValue;      // 检测量程[满偏检测量]
    double Sensitivity;     // 检测灵敏度(以量程单位表示的检测量/lsb)
    char DeteUnit[B16];     // 检测单位
    char RangeOptions[B96]; // 量程选项表
    double Temperature;     // 检测器温度[K]
    double H2Flow;          // H2流速[mL/min]
    double AirFlow;         // Air流速[mL/min]
    double RefFlow;         // TCD参考流速[mL/min]
    double AnodeFlow;       // ECD阳极流速[mL/min]
    double Current;         // 检测器电流[mA, ECD为0.1nA]
    char MakeupGas[B16];    // 尾吹气体(N2, H2, He, Ar氩气, CH4, Unknown)
    double MakeupFlow;      // 尾吹流速[mL/min]
    int32_t MakeupMode;     // 尾吹模式(makeup=const, col+makeup=const)
    int32_t GC_RangeIDInc;  // GC之FID/NPD/FPD的量程ID+1 (0x115及后续版本)
    double WaveLength;      // 检测波长[nm]
    int32_t WaveLengthMode; // 波长模式(Constant, Programmed)
    double SuppCurrent;     // 抑制器电流[mA]
    BOOL SuppAvailable;     // 抑制器是否有效
#ifdef _USRDLL
    // 构造函数
    TDetectCond();
#endif
};
#endif

#ifndef TAG_TAUXCOND
#define TAG_TAUXCOND
// 辅助区条件
struct TAuxCond
{
    BOOL Available;     // 是否有效
    int32_t Type;       // 类别
    char TypeAbbr[B8];  // 类别缩写
    char TypeName[B32]; // 类别名
    char Model[B32];    // 型号
    int32_t SensType;   // 传感类别(0-温度, 1-压力, 2-流量)
    BOOL OnOff;         // 开关状态
    int32_t PosNo;      // 位置号(从1算起)
    double Temperature; // 温度[K]
    int32_t TempMode;   // 温度模式(0-Constant, 1-Programmed)
    double Pressure;    // 压力[psi]
    int32_t PresMode;   // 压力模式(0-Constant, 1-Programmed)
    double Flow;        // 流量[mL/min]
    int32_t FlowMode;   // 流量模式(0-Constant, 1-Programmed)
#ifdef _USRDLL
    // 构造函数
    TAuxCond();
#endif
};
#endif

#ifndef TAG_TPUMPCOND
#define TAG_TPUMPCOND
// 泵条件
struct TPumpCond
{
    BOOL Available;        // 是否有效
    int32_t Type;          // 类别(恒流, 二元梯度, 三元梯度, 四元梯度)
    int32_t GradPresMode;  // 梯度压力模式(低压, 高压)
    double MaxPressure;    // 最高压力[psi]
    double MinPressure;    // 最低压力[psi]
    char Model[B32];       // 型号
    double TotalFlow;      // 泵流量[mL/min]
    double Pressure;       // 泵压[psi]
    double SolRatio[C4];   // 溶剂配比[%]
    BOOL SolUsed[C4];      // 溶剂是否被采用
    char SolName[C4][B32]; // 溶剂名称
    char FlowUnit[B16];    // 泵流量单位[mL/min, …]
    char PresUnit[B16];    // 泵压单位[Mpa, psi, bar]
#ifdef _USRDLL
    // 构造函数
    TPumpCond();
#endif
};
#endif

#ifndef TAG_TRAMPITEM
#define TAG_TRAMPITEM
// 温度(压力/流量)升降程序
struct TRampItem
{
    double RampRate;   // 升降速率[℃/min, psi/min, mL/min]
    double FinalValue; // 终值[K, psi, mL/min]
    double HoldTime;   // 保持时间[min]
    double TotalTime;  // 总计时间[min]
#ifdef _USRDLL
    // 构造函数
    TRampItem() : RampRate(0.0), FinalValue(0.0), HoldTime(0.0), TotalTime(0.0) {}
#endif
};
#endif

#ifndef TAG_TPUMPGRADITEM
#define TAG_TPUMPGRADITEM
// 泵梯度程序
struct TPumpGradItem
{
    double Time;         // 时间[min]
    double TotalFlow;    // 总流量[mL/min]
    double SolRatio[C4]; // 各溶剂占的比率[%]
#ifdef _USRDLL
    // 构造函数
    TPumpGradItem() : Time(0.0), TotalFlow(0.0), SolRatio{0.0, 0.0, 0.0, 0.0} {};
#endif
};
#endif

#ifndef TAG_TWAVELENGTHITEM
#define TAG_TWAVELENGTHITEM
// 波长程序
struct TWaveLengthItem
{
    double Time;   // 时间[min]
    int32_t Value; // 波长
#ifdef _USRDLL
    // 构造函数
    TWaveLengthItem() : Time(0.0), Value(0) {}
#endif
};
#endif

#ifndef TAG_TFLOATRAMPITEM
#define TAG_TFLOATRAMPITEM
// 单精度浮点数阶升数据项
struct TFloatRampItem
{
    float RampRate;   // 升降速率[℃/min, psi/min, mL/min]
    float FinalValue; // 终值[K, psi, mL/min]
    float HoldTime;   // 保持时间[min]
    float TotalTime;  // 总计时间[min]
#ifdef _USRDLL
    // 构造函数
    TFloatRampItem() : RampRate(0.0f), FinalValue(0.0f), HoldTime(0.0f), TotalTime(0.0f) {}
#endif
};
#endif

#ifndef TAG_TAUXCONDEX
#define TAG_TAUXCONDEX
// 扩充的辅助区条件
struct TAuxCondEx
{
    BOOL Available;               // 是否有效
    int32_t Type;                 // 类别(辅助加热区类型/辅助压力的气体类型)
    char TypeAbbr[B8];            // 类别缩写
    char TypeName[B32];           // 类别名
    char Model[B32];              // 型号(即辅助区说明)
    int32_t SensType;             // 传感类别(0-温度, 1-压力, 2-流量)
    BOOL OnOff;                   // 开关状态
    int32_t PosNo;                // 位置号(从1算起)
    TFloatRampItem RampItems[C8]; // 阶升数据(含初时值, 温度-K, 压力-psi, 流量-mL/min)
#ifdef _USRDLL
    // 构造函数
    TAuxCondEx();
#endif
};
#endif

struct TInstCond
{
    char Name[B256];                      // 仪器条件名
    TInstHead InstHead;                   // 仪器条件头信息
    TOvenCond OvenCond;                   // 柱箱条件
    TInletCond InletCond;                 // 进样口条件
    TColumnCond ColumnCond;               // 色谱柱条件
    TDetectCond DetectCond;               // 检测器条件
    TAuxCond AuxCond;                     // 辅助区条件
    TPumpCond PumpCond;                   // 泵条件
    TRampItem OvenTempItems[C64];         // 柱箱程序升温梯度
    TRampItem InletTempItems[C64];        // 进样口程序升温梯度
    TRampItem ColumnPFItems[C64];         // 色谱柱程序压力梯度
    TRampItem MakeupFlowItems[C64];       // 吹扫气程序流量梯度
    TPumpGradItem PumpGradItems[C64];     // 泵程序流量梯度
    TWaveLengthItem WaveLengthItems[C64]; // 光谱箱程序波长梯度
    TAuxCondEx AuxCondExs[C64];           // 扩充的辅助区条件
    int32_t OvenTempItemsCount;           // 柱箱程序升温梯度柱箱程序升温梯度有效个数
    int32_t InletTempItemsCount;          // 进样口程序升温梯度有效个数
    int32_t ColumnPFItemsCount;           // 色谱柱程序压力梯度有效个数
    int32_t MakeupFlowItemsCount;         // 吹扫气程序流量梯度有效个数
    int32_t PumpGradItemsCount;           // 泵程序流量梯度有效个数
    int32_t WaveCountItemsCount;          // 光谱箱程序波长梯度有效个数
    int32_t AuxCondExsCount;              // 扩充的辅助区条件有效个数
#ifdef _USRDLL
    // 构造函数
    TInstCond();
#endif
};

// 积分结果表
struct TAnalResult
{
    double Area;       // 峰面积(uV*s)
    double AreaPer;    // 面积%
    double Conc;       // 含量
    double Areas;      // 峰起点面积(uV*s)
    double Arear;      // 峰顶点面积(uV*s)
    double Areae;      // 峰落点面积(uV*s)
    double ALeft;      // 左峰面积
    double ARight;     // 右峰面积
    int32_t Idno;      // 组份号
    char Name[B32];    // 组份名
    float RTime;       // 保留时间(min.)
    float Height;      // 峰高(uV)
    char TypeCode[B4]; // 峰类型码
    float W50;         // 半高峰宽(min.)
    float Sigma5;      // 5Sigma峰宽(min.)
    float Plates;      // 理论塔片数 = 5.545*(Tr/W50)^2
    float Resolution;  // 分离度= 2.35478/2*(Tr2-Tr1)/(W50_2+W50_1)
    float Symmetry;    // USP拖尾因子 = 5%峰高宽/(2*5%峰高的左宽)
    float M1;          // 统计要素中的平均保留时间
    float M2;          // 统计要素中的峰畸变(展宽)
    float fts;         // 峰起点时间
    float fte;         // 峰落点时间
    int32_t ts;        // 峰起点时间(与采样频率有关)
    float tr;          // 峰顶点时间(与采样频率有关)
    int32_t te;        // 峰落点时间(与采样频率有关)
    float hs;          // 峰起点高度(uV)
    float hsv;         // 峰起点与积分基线垂直相交处的高度(uV)
    float hr;          // 峰顶点高度(uV)
    float he;          // 峰落点高度(uV)
    float hev;         // 峰落点与积分基线垂直相交处的高度(uV)
    char ReserveX[B4]; // 保留字段X
#ifdef _USRDLL
    // 构造函数
    TAnalResult();
#endif
};

// 综合结果表
struct TSynResult
{
    char Name[B32];         // 组分名/组名
    int32_t Type;           // 0-组分, 1-连续组, 2-间断组, 3-未知峰合计, 4-外部组分, 5-主要组成, -1-合计
    int32_t OkState;        // 0-未检出, 1-偏低, 2-偏高, 3-OK
    float Tr;               // 保留时间
    float Band;             // 带宽
    float cLower;           // 品控下限
    float cUpper;           // 品控上限
    double Area;            // 组累计峰面积
    double Height;          // 组累计峰高
    double Conc;            // 实测含量
    double ConcEx;          // 含量扩充(如发热量、TVOC标准状态含量等)
    float dLimit;           // 检出限
    int32_t ConcUnitFactor; // 浓度单位因子值
#ifdef _USRDLL
    // 构造函数
    TSynResult();
#endif
};

// 手动事件表
struct TEventList
{
    float ts;           // 起始时间(min.)
    float te;           // 结束时间(min.)
    EVENT event;        // 时间事件
    TPRGPARA paraValue; // 参数值，需根据不同事件解析成bool、int或double
    BOOL enable;        // 是否有效
    int32_t channelNo;  // 通道号
    int32_t order;      // 显示顺序
#ifdef _USRDLL
    // 构造函数
    TEventList() : ts(0.0f), te(0.0f), event(NOEVENT), paraValue({0}), enable(0) {}
#endif
};

// 组份表
struct TCompList
{
    float f0;           // 校正因子常数项
    float f1;           // 校正因子一次项
    float f2;           // 校正因子二次项
    float f3;           // 校正因子三次项
    float k;            // 扩充系数k
    float k1;           // 扩充系数k1
    float cLower;       // 品控下限
    float cUpper;       // 品控上限
    float r;            // 最小二乘法求取校正因子的相关系数
    E_BASEDON basedOn;  // 定量基准(0-面积, 1-峰高)
    double weight;      // 组份重量
    char Name[B32];     // 组份名
    float Time;         // 保留时间(min.)
    float band;         // 带宽(min.)
    int16_t istdNoSelf; // 拟引入的内标物号
    int16_t TypeEx;     //
    int16_t istdNoUsed; // 被标定的内标物号
    int16_t channelNo;  // 通道号
    int16_t order;      // 显示顺序
#ifdef _USRDLL
    // 构造函数
    TCompList();
#endif
};

// 分组表
struct TGroupList
{
    char Name[B32];         // 组名
    char IdNames[C64][B32]; // 组分名表
    char RefIdName[B32];    // 参考组分
    BOOL Continuous;        // 是否连续组
    BOOL NeedRefId;         // 是否需要参考组分
    float tLower;           // 时间下限(min.)
    float tUpper;           // 时间上限(min.)
    float cLower;           // 品控下限
    float cUpper;           // 品控上限W
    float dLimit;           // 检出限
    int32_t ConcUnitFactor; // 浓度单位因子值
    int32_t channelNo;      // 通道号
    int32_t order;          // 显示顺序
#ifdef _USRDLL
    // 构造函数
    TGroupList();
#endif
};

// 分段校正数据项
struct TSegmentItem
{
    double x; // 自变量值
    double a; // 校正系数a
    double b; // 校正系数b
#ifdef _USRDLL
    // 构造函数
    TSegmentItem() : x(0.0), a(0.0), b(0.0) {}
#endif
};

// 分段校正表
struct TSegmentList
{
    int32_t SegmentMode;           // 分段校正模式
    int32_t SegmentCount;          // 分段数量
    TSegmentItem SegmentItem[C16]; // 分段校正数据项数组
    int32_t channelNo;             // 通道号
    int32_t order;                 // 显示顺序
#ifdef _USRDLL
    // 构造函数
    TSegmentList();
#endif
};

// 校正头信息
struct TCalibHead
{
    int32_t CurveType; // 校正曲线类型
    int32_t ZeroType;  // 零点类型
    int32_t IdtCount;  // 标识数量
#ifdef _USRDLL
    // 构造函数
    TCalibHead() : CurveType(0), ZeroType(0), IdtCount(0) {}
#endif
};

// 校正表，记录数=参与校正的标谱图数
struct TCalibList
{
    char OrgName[B256];   // 原始文件名
    char GUID[B64];       // 全球唯一标识
    double StdConc[C256]; // 标准浓度数组
    double Resp[C256];    // 响应值数组
    double shift[C256];   // 偏移量数组
    int32_t channelNo;    // 通道号
    int32_t order;        // 显示顺序
#ifdef _USRDLL
    // 构造函数
    TCalibList();
#endif
};

// 校正结果表，记录数=组份数
struct TCalibResult
{
    int32_t Idno;      // 组份号
    char Name[B32];    // 组份名
    double f0;         // 校正因子常数项
    double f1;         // 校正因子一次项
    double f2;         // 校正因子二次项
    double f3;         // 校正因子三次项
    double r;          // 相关系数
    int32_t channelNo; // 通道号
    int32_t order;     // 显示顺序
#ifdef _USRDLL
    // 构造函数
    TCalibResult();
#endif
};

// 谱图原始数据
struct TRawItem
{
    int16_t Status;
    int32_t Time;
    int32_t Data;
    bool operator==(const TRawItem &item) const
    {
        return Status == item.Status && Time == item.Time && Data == item.Data;
    }
};

#pragma pack(push, 1)
struct TMethodHead_
{
    int32_t Identifier;    // 标识符
    int32_t Version;       // 版本号
    char Name[B64];        // 名称
    char GUID[B64];        // 全球唯一标识
    char ProjectID[B64];   // 项目ID
    char ProjectName[B64]; // 项目名称
    int32_t CreateTime;    // 创建时间
    int32_t UpdateTime;    // 更新时间
    char RelatedID[B64];   // 相关ID
    char Note[B128];       // 备注
    TEPara EPara;          // 计算参数
    TIPara IPara;          // 积分参数
    E_QUALITBY QualitBy;   // 定性模式
    TDLLMETRIC metric;     // 标样用量
    AUTOIPARA autoIPara;   // 自动参数

    TUkPkFactor UkPkFactor[C4]; // 品控因子
    double XUnit[C4];           // 采样周期(1/Freq)到时间标称单位(XLabel)的换算系数(XUnit=1/(60*Freq))
    double YUnit[C4];           // 检测器标称单位(mV)到采集器最小信号单位(uV)的转换系数(默认值=1000)
    TCalibHead CalibHead[C4];   // 校正头信息

    int32_t EventListOffset;   // 手动事件表偏移量
    int32_t EventListCount;    // 手动事件表项目数
    int32_t CompListOffset;    // 组份表偏移量
    int32_t CompListCount;     // 组份表项目数
    int32_t GroupListOffset;   // 分组表偏移量
    int32_t GroupListCount;    // 分组表项目数
    int32_t SegmentListOffset; // 分段校正表偏移量
    int32_t SegmentListCount;  // 分段校正表项目数
    int32_t CalibListOffset;   // 校正表偏移量
    int32_t CalibListCount;    // 校正表项目数
    int32_t CalibResultOffset; // 校正结果表偏移量
    int32_t CalibResultCount;  // 校正结果表项目数
#ifdef _USRDLL
    // 构造函数
    TMethodHead_();
#endif
};

// 方法数据头
struct TMethodHead : TMethodHead_
{
    char Reserved1[B1024 - sizeof(TMethodHead_)]; // 保留区域1
#ifdef _USRDLL
    // 构造函数
    TMethodHead();
#endif
};

struct TOrgHead_
{
    int32_t Identifier;    // 标识符
    int32_t Version;       // 版本号
    char Name[B64];        // 名称
    char GUID[B64];        // 全球唯一标识
    int32_t Type;          // 类型
    char ProjectID[B64];   // 项目ID
    char ProjectName[B64]; // 项目名称

    // 检测器编号: 0xabcdefgh，
    // ab位定义第一信号通道对应的检测器ID，
    // cd位定义第二信号通道对应的检测器ID，
    // ef位定义第三信号通道对应的检测器ID，
    // gh位定义第四信号通道对应的检测器ID，
    // 不支持的信号通道用数值0xff填充对应位。
    int32_t Detector;              // 检测器编号
    int32_t CreateTime;            // 创建时间
    int32_t UpdateTime;            // 更新时间
    E_SUB_TYPE BlankMode;          // 扣除空白模式
    float Frequency;               // 采样频率
    TSample Sample[C4];            // 样品信息
    TInject Inject[C4];            // 进样信息
    char XUnit[C4][B32];           // X轴单位数组
    char YUnit[C4][B32];           // Y轴单位数组
    char RelatedID[C4][B64];       // 相关ID数组
    char Note[C4][B128];           // 备注数组
    int32_t InstCondOffset[C4];    // 仪器条件偏移量
    int32_t InstCondLength[C4];    // 仪器条件长度
    int32_t RawDataOffset[C4];     // 原始数据偏移量
    int32_t RawDataCount[C4];      // 原始数据项目数
    int32_t MethodOffset;          // 方法文件偏移量
    int32_t MethodLength;          // 方法文件数据长度
    int32_t AnalResultOffset[C4];  // 分析结果偏移量
    int32_t AnalResultCount[C4];   // 分析结果项目数
    int32_t SynResultOffset[C4];   // 综合结果偏移量
    int32_t SynResultCount[C4];    // 综合结果项目数
    int32_t StudyDataOffset[C4];   // 研究数据偏移量
    int32_t StudyDataCount[C4];    // 研究数据项目数
    int32_t BlankDataOffset[C4];   // 空白数据偏移量
    int32_t BlankDataCount[C4];    // 空白数据项目数
    int32_t BlankResultOffset[C4]; // 空白结果偏移量
    int32_t BlankResultCount[C4];  // 空白结果项目数
#ifdef _USRDLL
    // 构造函数
    TOrgHead_();
#endif
};

// 谱图数据头
struct TOrgHead : TOrgHead_
{
    char Reserved1[B8192 - sizeof(TOrgHead_)]; // 保留区域1
#ifdef _USRDLL
    // 构造函数
    TOrgHead();
#endif
};
#pragma pack(pop)

#ifdef _USRDLL
struct TMethodFile : public TMethodHead
{
    uint64_t HeadCRC;                            // 头部CRC校验值
    uint64_t DataCRC;                            // 数据CRC校验值
    std::shared_ptr<TEventList[]> EventList;     // 手动事件表智能指针
    std::shared_ptr<TCompList[]> CompList;       // 组份表智能指针
    std::shared_ptr<TGroupList[]> GroupList;     // 分组表智能指针
    std::shared_ptr<TSegmentList[]> SegmentList; // 分段校正表智能指针
    std::shared_ptr<TCalibList[]> CalibList;     // 校正表智能指针
    std::shared_ptr<TCalibResult[]> CalibResult; // 校正结果表智能指针
    char Reserved2[B1024 - 8 * 8];               // 保留区域2
    // 构造函数
    TMethodFile();
    // 计算头部长度
    int32_t getHeadLength() const;
    // 计算数据长度
    int32_t getDataLength() const;
    // 计算总长度
    int32_t getTotalLength() const;
    // 从缓冲区复制头部信息
    bool copyHeadFromBuffer(const BYTE *data, int32_t dataLength);
    // 将头部信息复制到缓冲区
    bool copyHeadToBuffer(BYTE *data, int32_t dataLength) const;
    // 从缓冲区复制指针指向的数据
    bool copyPtrFromBuffer(const BYTE *data, int32_t dataLength);
    // 将指针指向的数据复制到缓冲区
    bool copyPtrToBuffer(BYTE *data, int32_t dataLength);
    // 将数据复制到缓冲区
    bool copyToBuffer(BYTE *data, int32_t dataLength);
    // 从缓冲区复制数据
    bool copyFromBuffer(BYTE *data, int32_t dataLength);
};

struct TOrgFile : public TOrgHead
{
    uint64_t HeadCRC;                               // 头部CRC校验值
    uint64_t DataCRC;                               // 数据CRC校验值
    std::shared_ptr<TInstCond> InstCond[C4];        // 仪器条件
    std::shared_ptr<TRawItem[]> RawData[C4];        // 原始数据
    std::shared_ptr<TMethodFile> Method;            // 积分方法
    std::shared_ptr<TAnalResult[]> AnalResult[C4];  // 分析结果
    std::shared_ptr<TSynResult[]> SynResult[C4];    // 综合结果
    std::shared_ptr<TRawItem[]> StudyData[C4];      // 学习基线数据
    std::shared_ptr<TRawItem[]> BlankData[C4];      // 空白数据
    std::shared_ptr<TAnalResult[]> BlankResult[C4]; // 空白结果
    char Reserved2[B1024 - 8 * 31];                 // 保留区域2
    // 构造函数
    TOrgFile();

    // 计算头部长度
    int32_t getHeadLength() const;
    // 计算数据长度
    int32_t getDataLength() const;
    // 计算总长度
    int32_t getTotalLength() const;
    // 从缓冲区复制头部信息
    bool copyHeadFromBuffer(const BYTE *data, int32_t dataLength);
    // 将头部信息复制到缓冲区
    bool copyHeadToBuffer(BYTE *data, int32_t dataLength) const;
    // 从缓冲区复制指针指向的数据
    bool copyPtrFromBuffer(const BYTE *data, int32_t dataLength);
    // 将指针指向的数据复制到缓冲区
    bool copyPtrToBuffer(BYTE *data, int32_t dataLength);
    // 将数据复制到缓冲区
    bool copyToBuffer(BYTE *data, int32_t dataLength);
    // 从缓冲区复制数据
    bool copyFromBuffer(BYTE *data, int32_t dataLength);
};
#endif

template <typename T>
bool copyListFromBuffer(const BYTE *data, int32_t &count, int32_t &offset, std::shared_ptr<T[]> &list, int32_t dataLength)
{
    if (count > 0 && offset > 0)
    {
        list = std::make_shared<T[]>(count);
        const T *pData = reinterpret_cast<const T *>((char *)data + offset);
        if (dataLength < offset + count * (int32_t)sizeof(T))
        {
            PUSH_ERROR("函数 copyListFromBuffer 数据空间不足(datalength=%d, offset=%d, count=%d)。", dataLength, offset, count);
            return false;
        }
        std::copy(pData, pData + count, list.get());
    }
    else
    {
        list = nullptr;
    }
    return true;
}

template <typename T>
bool copyListToBuffer(BYTE *data, int32_t &count, int32_t &offsetInStruct, std::shared_ptr<T[]> &list, int32_t &offset, int32_t dataLength)
{
    if (count > 0)
    {
        offsetInStruct = offset;
        if (dataLength < offset + count * (int32_t)sizeof(T))
        {
            PUSH_ERROR("函数 copyListFromBuffer 数据空间不足(datalength=%d, offset=%d, count=%d)。", dataLength, offset, count);
            return false;
        }
        std::copy(list.get(), list.get() + count, reinterpret_cast<T *>(data + offset));
        offset += count * sizeof(T);
    }
    else
    {
        offsetInStruct = 0;
    }
    return true;
}
template <typename T>
bool copyFromBufferArray(const BYTE *data, std::shared_ptr<T[]> *arr, int32_t *offsetArr, int32_t *countArr, int32_t chn, int32_t dataLength)
{
    if (offsetArr[chn] > 0 && countArr[chn] > 0)
    {
        arr[chn] = std::make_shared<T[]>(countArr[chn]);
        const T *pData = reinterpret_cast<const T *>((char *)data + offsetArr[chn]);
        if (dataLength < offsetArr[chn] + countArr[chn] * (int32_t)sizeof(T))
        {
            PUSH_ERROR("函数 copyFromBufferArray 数据空间不足(datalength=%d, offsetArr[%d]=%d, countArr[%d]=%d, sizeOf=%d)。",
                       dataLength, chn, offsetArr[chn], chn, countArr[chn], sizeof(T));
            return false;
        }
        std::copy(pData, pData + countArr[chn], arr[chn].get());
    }
    else
    {
        arr[chn] = nullptr;
    }
    return true;
}

template <typename T>
bool copyToBufferArray(BYTE *data, std::shared_ptr<T[]> *arr, int32_t *offsetArr, int32_t *countArr, int32_t chn, int32_t &offset, int32_t dataLength)
{
    if (arr[chn])
    {
        offsetArr[chn] = offset;
        if (dataLength < offsetArr[chn] + countArr[chn] * (int32_t)sizeof(T))
        {
            PUSH_ERROR("函数 copyToBufferArray 数据空间不足(datalength=%d, offsetArr[%d]=%d, countArr[%d]=%d, sizeOf=%d)。",
                       dataLength, chn, offsetArr[chn], chn, countArr[chn], sizeof(T));
            return false;
        }
        std::copy(arr[chn].get(), arr[chn].get() + countArr[chn], reinterpret_cast<T *>(data + offset));
        offset += countArr[chn] * sizeof(T);
    }
    else
    {
        offsetArr[chn] = 0;
    }
    return true;
}

#define COPY_FROM_BUFFER_C4(SubKey)                                                                 \
    for (int32_t chn = 0; chn < C4; ++chn)                                                          \
    {                                                                                               \
        if (isValidChannel(Detector, chn))                                                          \
        {                                                                                           \
            if (!copyFromBufferArray(data, SubKey, SubKey##Offset, SubKey##Count, chn, dataLength)) \
            {                                                                                       \
                PUSH_ERROR("COPY_FROM_BUFFER_C4 失败。");                                           \
                return false;                                                                       \
            }                                                                                       \
        }                                                                                           \
    }

#define COPY_TO_BUFFER_C4(SubKey)                                                                         \
    for (int32_t chn = 0; chn < C4; ++chn)                                                                \
    {                                                                                                     \
        if (isValidChannel(Detector, chn))                                                                \
        {                                                                                                 \
            if (!copyToBufferArray(data, SubKey, SubKey##Offset, SubKey##Count, chn, offset, dataLength)) \
            {                                                                                             \
                PUSH_ERROR("COPY_TO_BUFFER_C4 失败。");                                                   \
                return false;                                                                             \
            }                                                                                             \
        }                                                                                                 \
    }

#endif
